home *** CD-ROM | disk | FTP | other *** search
/ PC-X 1997 October / pcx14_9710.iso / swag / pointers.swg / 0039_Very Large 2d arrays.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-11-29  |  8.1 KB  |  296 lines

  1. > > I'm working on a program where it would be very convenient
  2. > >to use very large 2d arrays (40X3000 elements of type real, or
  3. > >thereabouts) Is there any way to do this in TP7?
  4. > >
  5. > See URL in sig, but you may need BP since you call for 720000 bytes or
  6. > thereabouts.  See also #FloatTypes.
  7. >
  8.  
  9. {
  10.  
  11. Leopoldo Salvo Massieu. e-mail lsm@teleline.es  -and-
  12. a900040@zipi.fi.upm.es
  13.  
  14. Object Storage is a zero-based array, just tell how many elements you 
  15. want to store and what's the size in bytes of each element (use sizeof). 
  16. It can allocate all heap available (also in Protected Mode). There's a
  17. little demo down.
  18. }
  19.  
  20. unit ALMACEN;
  21.  
  22. interface
  23.          USES GRAPH;
  24.  
  25.          const Not_enough_memory = -100;
  26.                Element_too_big = -101;
  27.                File_Not_Found = -102;
  28.                Error_Writing_File = -103;
  29.  
  30.          type pointerarray = array [0..16200] of pointer;
  31.  
  32.               {Zero-based array}
  33.               PStorage = ^Storage;
  34.               storage = object
  35.                           private
  36.                              elements_x_pointer, elem_size : word;
  37.                              num_pointers, last_pointer_size : word;
  38.                              data : ^pointerarray;
  39.                              max : longint;
  40.                              out_of_mem : boolean;
  41.                           public
  42.                              constructor init (num_elements : longint;
  43.                                                element_size : word);
  44.                              destructor done;
  45.                              procedure put (pos : longint; p : pointer);
  46.                              procedure get (pos : longint; VAR p :
  47. pointer);
  48.                              function save (filename : string) :
  49. integer; virtual;
  50.                              function load (filename : string) : 
  51. integer; virtual;
  52.                         end;
  53.  
  54.  
  55. implementation
  56.  
  57.  
  58. (****************************************
  59. object storage
  60. ****************************************)
  61.  
  62. const max_allocatable_ram : word = 65528;
  63.  
  64. constructor storage.init;
  65. var memoria : longint;
  66.     aux : longint;
  67.     pneeded : word;
  68.     i : integer;
  69. begin
  70.     memoria:=num_elements*element_size;
  71.     elements_x_pointer:=max_allocatable_ram div element_size;
  72.     max:=num_elements;
  73.     pneeded:=(num_elements*element_size div max_allocatable_ram)+2;
  74.     if (memoria+16000>memavail) or (elements_x_pointer=0)
  75.        or (pneeded>16200) then
  76.      begin
  77.        Out_Of_Mem:=true;
  78.        Fail;
  79.      end;
  80.     getmem (data, pneeded*sizeof(pointer));
  81.     num_pointers:=0;
  82.     for i:=1 to pneeded do data^[i]:=Nil;
  83.     while num_elements>elements_x_pointer do
  84.       begin
  85.         getmem (data^[num_pointers], elements_x_pointer*element_size);
  86.         fillchar (data^[num_pointers]^,elements_x_pointer*element_size,0);
  87.         inc (num_pointers);
  88.         dec (num_elements, elements_x_pointer);
  89.       end;
  90.     if (num_elements>0) then
  91.      begin
  92.        getmem (data^[num_pointers], num_elements*element_size);
  93.        fillchar (data^[num_pointers]^, num_elements*element_size,0);
  94.        last_pointer_size:=num_elements*element_size
  95.      end
  96.     else
  97.        last_pointer_size:=elements_x_pointer*element_size;
  98.     elem_size:=element_size;
  99. end;
  100.  
  101. destructor storage.done;
  102. var i : longint;
  103. begin
  104.    if num_pointers>0 then
  105.     for i:=0 to num_pointers-1 do
  106.      if data^[i]<>NIL then freemem (data^[i], elements_x_pointer*elem_size);
  107.    if data^[num_pointers]<>nil then freemem (data^[num_pointers], last_pointer_size);
  108.    if data<>NIL then freemem (data, num_pointers*sizeof(pointer));
  109.    max:=-1;
  110. end;
  111.  
  112. procedure storage.put;
  113. type table = array [0..65528] of byte;
  114. var numpunt : longint;
  115.     desp : word;
  116. begin
  117.   if (pos>=0) and (pos<max) then
  118.    begin
  119.     numpunt:=pos div elements_x_pointer;
  120.     desp:=(pos-numpunt*elements_x_pointer)*elem_size;
  121.     move (p^, table(data^[numpunt]^)[desp], elem_size);
  122.    end
  123.   else
  124.    inc(pos)
  125. end;
  126.  
  127. procedure storage.get;
  128. type table = array [0..65528] of byte;
  129. var numpunt : longint;
  130.     desp : word;
  131. begin
  132.   if (pos>=0) and (pos<max) then
  133.    begin
  134.     numpunt:=pos div elements_x_pointer;
  135.     desp:=(pos-numpunt*elements_x_pointer)*elem_size;
  136.     p:=addr(table(data^[numpunt]^)[desp]);
  137.    end
  138.   else
  139.    halt (23)
  140. end;
  141.  
  142. function storage.save;
  143. var f : file;
  144.     i, res : integer;
  145.     escr : word;
  146. begin
  147.    assign (f, filename);
  148.    {$I-}
  149.       rewrite (f,1);
  150.    {$I+}
  151.    res:=ioresult;
  152.    if res=0 then
  153.     begin
  154.      {$I-}
  155.        blockwrite (f, elements_x_pointer, sizeof(elements_x_pointer));
  156.        blockwrite (f, elem_size, sizeof(elem_size));
  157.        blockwrite (f, num_pointers, sizeof(num_pointers));
  158.        blockwrite (f, last_pointer_size, sizeof(last_pointer_size));
  159.        blockwrite (f, max, sizeof(max));
  160.      {$I+}
  161.      res:=ioresult;
  162.      if res<>0 then begin save:=res; exit; end;
  163.      if num_pointers>0 then
  164.       begin
  165.         for i:=0 to num_pointers-1 do
  166.          begin
  167.           {$I-}
  168.            blockwrite (f, data^[i]^, elements_x_pointer*elem_size,escr);
  169.           {$I+}
  170.           res:=ioresult; if res<>0 then begin write ('{#',res,',',escr,'}'); break; end
  171.          end;
  172.        if res=0 then
  173.         begin
  174.          {$I-}
  175.            blockwrite (f, data^[num_pointers]^, last_pointer_size,  escr);
  176.          {$I+}
  177.          res:=ioresult; if res<>0 then begin write ('{@',res,',',escr,'}'); end
  178.         end;
  179.       end;
  180.     end;
  181.    save:=res;
  182.    {$I-}
  183.      close (f);
  184.    {$I+}
  185.    res:=ioresult;
  186. end;
  187.  
  188. function storage.load;
  189. var f : file;
  190.     i, res : integer;
  191.     lect,exp,es,np,lps :word;
  192.     m : longint;
  193. begin
  194.    assign (f, filename);
  195.    {$I-}
  196.       reset (f,1);
  197.    {$I+}
  198.    res:=ioresult;
  199.    if res<>0 then begin load:=res; exit; end;
  200.    {$I-}
  201.      blockread (f, exp, sizeof(elements_x_pointer));
  202.      blockread (f, es, sizeof(elem_size));
  203.      blockread (f, np, sizeof(num_pointers));
  204.      blockread (f, lps, sizeof(last_pointer_size));
  205.      blockread (f, m, sizeof(max));
  206.    {$I+}
  207.    res:=ioresult;
  208.    if res<>0 then begin load:=res; exit; end;
  209.    if ( (np>0) and (longint(exp)*(np-1)*es+lps+32000>memavail) ) or
  210.       ( (np=0) and (lps+32000>memavail) ) then
  211.        begin writeln; writeln ('np: ', np, 'exp: ', exp, 'es: ', es,' 
  212.              lps: ',lps); out_of_mem:=true; exit; end;
  213.    done;
  214.    elements_x_pointer:=exp; elem_size:=es; num_pointers:=np;
  215.    last_pointer_size:=lps; max:=m;
  216.    getmem (data, num_pointers*sizeof(pointer));
  217.    if num_pointers>0 then for i:=0 to num_pointers-1 do
  218.          getmem (data^[i], elements_x_pointer*elem_size);
  219.    getmem (data^[num_pointers], last_pointer_size);
  220.    out_of_mem:=false;
  221.    if num_pointers>0 then
  222.     begin
  223.      for i:=0 to num_pointers-1 do
  224.       begin
  225.        {$I-}
  226.         blockread (f, data^[i]^, elements_x_pointer*elem_size, lect);
  227.        {$I+}
  228.        res:=ioresult; if res<>0 then begin write ('{&',res,',',lect,'}'); break; end
  229.       end;
  230.      if res=0 then
  231.       begin
  232.        {$I-}
  233.         blockwrite (f, data^[num_pointers]^, last_pointer_size);
  234.        {$I+}
  235.        res:=ioresult; if res<>0 then begin write ('{&',res,',',lect,'}'); end
  236.       end;
  237.     end;
  238.    load:=res;
  239.    {$I-}
  240.      close (f);
  241.    {$I+}
  242.    res:=ioresult;
  243. end;
  244.  
  245. end. {of unit almacen}
  246.  
  247.  
  248.  
  249. {and now a little demo (compile under protected mode or there will be 
  250. not enough heap}
  251.  
  252.  
  253. uses almacen;
  254.  
  255. type  ptipe = ^tipe;
  256.       tipe = real;
  257.  
  258. const rows : longint = 40;
  259.       columns : longint = 30000;
  260.  
  261. var store : ^storage;
  262.  
  263.     y,x : longint; {y=1..40
  264.                     x=1..30000}
  265.  
  266.     r : tipe;
  267.     pr : ptipe;
  268.  
  269. begin
  270.    new (store, init(rows*columns, sizeof(real)));
  271.    if (store=nil) then
  272.     begin
  273.       writeln ('Out of memory.');
  274.       exit;
  275.     end;
  276.    for y:=0 to rows-1 do
  277.     for x:=0 to columns-1 do
  278.      begin
  279.       r:=y*columns+x;
  280.       store^.put(y*columns+x, @r);
  281.      end;
  282.    for y:=0 to rows-1 do
  283.     for x:=0 to columns-1 do
  284.      begin
  285.       store^.get(y*columns+x, pointer(pr));
  286.       if (pr^<>y*columns+x) then
  287.        begin
  288.         writeln ('Error... (Hopefully Impossible)');
  289.         break;
  290.        end
  291.       else write ('.');
  292.      end;
  293.    dispose (store, done);
  294. end.
  295.  
  296.